using System;
using UnityEngine.Rendering;

namespace UnityEngine.Recorder.Input
{
	public class Camera360Input : BaseRenderTextureInput
	{
		private bool m_ModifiedResolution;

		private Shader m_shCopy;

		private TextureFlipper m_VFlipper = new TextureFlipper();

		private RenderTexture m_Cubemap1;

		private RenderTexture m_Cubemap2;

		public Camera360InputSettings settings360 => (Camera360InputSettings)base.settings;

		private Camera targetCamera
		{
			get;
			set;
		}

		public Shader copyShader
		{
			get
			{
				if (m_shCopy == null)
				{
					m_shCopy = Shader.Find("Hidden/Recorder/Inputs/CBRenderTexture/CopyFB");
				}
				return m_shCopy;
			}
			set
			{
				m_shCopy = value;
			}
		}

		public override void BeginRecording(RecordingSession session)
		{
			if (settings360.m_FlipFinalOutput)
			{
				m_VFlipper = new TextureFlipper();
			}
			base.outputWidth = settings360.m_OutputWidth;
			base.outputHeight = settings360.m_OutputHeight;
		}

		public override void NewFrameStarting(RecordingSession session)
		{
			switch (settings360.source)
			{
			case EImageSource.MainCamera:
				if (targetCamera != Camera.main)
				{
					targetCamera = Camera.main;
				}
				break;
			case EImageSource.TaggedCamera:
			{
				string cameraTag = settings360.m_CameraTag;
				if (targetCamera == null || targetCamera.gameObject.tag != cameraTag)
				{
					try
					{
						GameObject[] array = GameObject.FindGameObjectsWithTag(cameraTag);
						if (array.Length > 0)
						{
							UnityEngine.Debug.LogWarning("More than one camera has the requested target tag:" + cameraTag);
						}
						targetCamera = array[0].transform.GetComponent<Camera>();
					}
					catch (UnityException)
					{
						UnityEngine.Debug.LogWarning("No camera has the requested target tag:" + cameraTag);
						targetCamera = null;
					}
				}
				break;
			}
			default:
				throw new ArgumentOutOfRangeException();
			}
			PrepFrameRenderTexture();
		}

		public override void NewFrameReady(RecordingSession session)
		{
			float stereoSeparation = targetCamera.stereoSeparation;
			StereoTargetEyeMask stereoTargetEye = targetCamera.stereoTargetEye;
			if (settings360.m_RenderStereo)
			{
				targetCamera.stereoSeparation = settings360.m_StereoSeparation;
				targetCamera.stereoTargetEye = StereoTargetEyeMask.Both;
				targetCamera.RenderToCubemap(m_Cubemap1, 63, Camera.MonoOrStereoscopicEye.Left);
				targetCamera.stereoSeparation = settings360.m_StereoSeparation;
				targetCamera.stereoTargetEye = StereoTargetEyeMask.Both;
				targetCamera.RenderToCubemap(m_Cubemap2, 63, Camera.MonoOrStereoscopicEye.Right);
			}
			else
			{
				targetCamera.RenderToCubemap(m_Cubemap1, 63, Camera.MonoOrStereoscopicEye.Mono);
			}
			if (settings360.m_RenderStereo)
			{
				m_Cubemap1.ConvertToEquirect(base.outputRT, Camera.MonoOrStereoscopicEye.Left);
				m_Cubemap2.ConvertToEquirect(base.outputRT, Camera.MonoOrStereoscopicEye.Right);
			}
			else
			{
				m_Cubemap1.ConvertToEquirect(base.outputRT);
			}
			if (settings360.m_FlipFinalOutput)
			{
				m_VFlipper.Flip(base.outputRT);
			}
			targetCamera.stereoSeparation = stereoSeparation;
			targetCamera.stereoTargetEye = stereoTargetEye;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if ((bool)m_Cubemap1)
				{
					UnityHelpers.Destroy(m_Cubemap1);
				}
				if ((bool)m_Cubemap2)
				{
					UnityHelpers.Destroy(m_Cubemap2);
				}
				if (m_VFlipper != null)
				{
					m_VFlipper.Dispose();
				}
			}
			base.Dispose(disposing);
		}

		private bool PrepFrameRenderTexture()
		{
			if (base.outputRT != null)
			{
				if (base.outputRT.IsCreated() && base.outputRT.width == base.outputWidth && base.outputRT.height == base.outputHeight)
				{
					return false;
				}
				ReleaseBuffer();
			}
			base.outputRT = new RenderTexture(base.outputWidth, base.outputHeight, 24, RenderTextureFormat.ARGB32)
			{
				dimension = TextureDimension.Tex2D,
				antiAliasing = 1
			};
			m_Cubemap1 = new RenderTexture(settings360.m_MapSize, settings360.m_MapSize, 24, RenderTextureFormat.ARGB32)
			{
				dimension = TextureDimension.Cube
			};
			m_Cubemap2 = new RenderTexture(settings360.m_MapSize, settings360.m_MapSize, 24, RenderTextureFormat.ARGB32)
			{
				dimension = TextureDimension.Cube
			};
			return true;
		}
	}
}
